#import imp
from django.db.models import Q,F
from django.http import response
from django.shortcuts import render,get_object_or_404
from django.http import HttpResponse,HttpResponseRedirect

from django.utils.decorators import method_decorator
from django.contrib.auth.mixins import LoginRequiredMixin

from django.views.generic import DetailView,ListView
from django.urls import reverse
from django.core.cache import cache

from config.models import SideBar
from .models import Post,Tag,Category
from comment.forms import CommentForm
from comment.models import Comment

from datetime import date

#from blog.models import Post,Tag,Category

# Create your views here.


class CommonViewMixin:
    def get_context_data(self,**kwargs):
        context=super().get_context_data(**kwargs)
        context.update({
            'sidebars':SideBar.get_all(),
        })
        context.update(Category.get_navs())
        return context

class PostDetailView(CommonViewMixin,DetailView):
    queryset=Post.latest_posts()
    template_name='blog/detail.html'
    context_object_name='post'
    pk_url_kwarg='post_id'
    
    def get(self,request,*args, **kwargs):
        response=super().get(request,*args, **kwargs)
        self.handle_visited()
        return response
        #Post.objects.filter(pk=self.object.id).update(pv=F('pv')+1,uv=F('uv')+1)

    def handle_visited(self):
        increase_pv=False
        increase_uv=False
        uid=self.request.uid
        pv_key='pv:%s:%s' % (uid,self.request.path)
        uv_key='uv:%s:%s:%s' % (uid,str(date.today()),self.request.path)

        if not cache.get(pv_key):
            increase_pv=True
            cache.set(pv_key,1,1*60)    #1分钟有效

        if not cache.get(uv_key):
            increase_pv=True
            cache.set(pv_key,1,24*60*60)    #24小时有效
        # pv访问量, 即页面浏览量或点击量，衡量网站用户访问的网页数量；在一定统计周期内用户每打开或刷新一个页面就记录1次，多次打开或刷新同一页面则浏览量累计。
        # uv独立访客，统计1天内访问某站点的用户数(以cookie为依据);访问网站的一台电脑客户端为一个访客。可以理解成访问某网站的电脑的数量。网站判断来访电脑的身
        # 份是通过来访电脑的cookies实现的。如果更换了IP后但不清除cookies，再访问相同网站，该网站的统计中UV数是不变的。如果用户不保存cookies访问、清除了
        # cookies或者更换设备访问，计数会加1。00:00-24:00内相同的客户端多次访问只计为1个访客。
        if increase_pv and increase_uv:
            Post.objects.filter(pk=self.object.id).update(pv=F('pv')+1,uv=F('uv')+1)
        elif increase_pv:
            Post.objects.filter(pk=self.object.id).update(pv=F('pv')+1)
        elif increase_uv:
            Post.objects.filter(pk=self.object.id).update(uv=F('uv')+1)
        #   上面的逻辑很直观，用于判断是否有缓存，如果没有则进行+1操作，最后的几个条件语句是避免执行两次更新操作。
        #   Django的缓存在未配置的情况下，使用的是内存缓存。如果是单进程，这没有问题，如果是多进程，就会出现问题。
        # 因为内存缓存是进程间独立的。
        #   因此，可以暂时这么用。或者，你可以尝试其他配置（对于小型系统，直接使用文件系统或者数据库表缓存即可；对
        # 于大型系统，推荐使用memcached或者Redis。）后面会专门来讲缓存部分。


        #调试用
        #from django.db import connection
        #print('哈哈哈')
        #print(connection.queries)
        #return response
    """
    #9.3.4 抽象出评论模块组件和Mixin后需要去掉此段代码
    def get_context_data(self,**kwargs):
        context=super().get_context_data(**kwargs)
        context.update({
            'comment_form':CommentForm,
            'comment_list':Comment.get_by_target(self.request.path),
        })
        return context
    #9.3.4 抽象出评论模块组件和Mixin后需要去掉此段代码
    """
class IndexView(CommonViewMixin,ListView):
    queryset=Post.latest_posts()
    paginate_by=5
    context_object_name='post_list'
    template_name='blog/list.html'

class PostListView(ListView):
    queryset=Post.latest_posts()
    paginate_by=1
    context_object_name='post_list'#如果不设置此项，在模板中需要使用object_list变量
    template_name='blog/list.html'

class CategoryView(IndexView):
    def get_context_data(self,**kwargs):
        #python中的可变参数，*arg表示任意多个无名参数，类型为tuple;**kwargs表示关键字参数，为dict。
        context=super().get_context_data(**kwargs)
        category_id=self.kwargs.get('category_id')
        category=get_object_or_404(Category,pk=category_id)
        context.update({
            'category':category,
        })
        return context

    def get_queryset(self):
        '''重写queryset，根据分类过滤'''
        queryset=super().get_queryset()
        category_id=self.kwargs.get('category_id')
        return queryset.filter(category_id=category_id)

class TagView(IndexView):
    def get_context_data(self,**kwargs):
        context=super().get_context_data(**kwargs)
        tag_id=self.kwargs.get('tag_id')
        tag=get_object_or_404(Tag,pk=tag_id)
        context.update({
            'tag':tag,
        })
        return context

    def get_queryset(self):
        '''重写queryset，根据分类过滤'''
        queryset=super().get_queryset()
        tag_id=self.kwargs.get('tag_id')
        return queryset.filter(tag__id=tag_id)#书中此处括号中第一个tigid为双下划线，不能改为单下划线，会出错
        
class SearchView(IndexView):
    #搜索页面
    def get_context_data(self):
        context=super().get_context_data()
        context.update({
            'keyword':self.request.GET.get('keyword','')
        })
        return context

    def get_queryset(self):
        queryset=super().get_queryset()
        keyword=self.request.GET.get('keyword','')
        if not keyword:
            return queryset
        return queryset.filter(Q(title__icontains=keyword) | Q(desc__icontains=keyword))
        #Q表达式实现了类似这样的sql语句：select * from post where title ilike '%<keyword>%' or desc ilike '%<keyword>%'

class AuthorView(IndexView):
    #作者页面
    def get_queryset(self):
        queryset=super().get_queryset()
        author_id=self.kwargs.get('owner_id')
        return queryset.filter(owner_id=author_id)